<template>
  <div>
    <div id="tableContainer">
      <table>
        <tbody>
        <tr v-for="(rowData, rowIndex) in tableList" :key="rowIndex">
          <td v-for="(header,colIndex) in tableHeaders"
              :key="`myTd_${rowIndex}_${colIndex}`"
              :id="'myTd_' + rowIndex + '_' + colIndex"
              class="tdBottomClass">
              <!--文本框-->
              <div class="editDiv" contenteditable="true"
                  :id="'cell_' + rowIndex + '_' + colIndex"
                  @input="adjustHeight($event.target, rowIndex, colIndex)">
              </div>
              <!--不使用伪元素来显示右边界,用div-->
              <div :id="'right_' + rowIndex + '_' + colIndex" class="tdRightClass"></div>
          </td>
        </tr>
        </tbody>
      </table>
    </div>
    <div id="context-menu" class="hidden">
      <ul>
        <li><a href="#" @click="addRow">添加一行</a></li>
        <li><a href="#" @click="deleteRow">删除一行</a></li>
        <li><a href="#" @click="addColumn">添加一列</a></li>
        <li><a href="#" @click="deleteColumn">删除一列</a></li>
        <li><a href="#" @click="addImage">插入图片</a></li>
      </ul>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableHeaders: ['col1', 'col2', 'col3'],
      tableList: [
        // 一个对象是一行元素    col123分别代表123列的数据
        {
          col1: '',
          col2: '',
          col3: '',
        }
      ],
      // 单元格的id  并非textarea的id
      currentClickEditDivCellId:'',
    };
  },
  methods: {
    /**
     * 调整单元格高度
     * @param editDiv
     * @param rowIndex
     * @param colIndex
     */
    adjustHeight(editDiv, rowIndex, colIndex) {
      editDiv.style.height = "100%";
      editDiv.style.marginTop = 0 + "px";
      editDiv.style.height = editDiv.scrollHeight + "px";

      // 给div模拟双向数据绑定
      const header = this.tableHeaders[colIndex];
      this.tableList[rowIndex][header] = editDiv.innerHTML;
      // console.log(editDiv.innerHTML)

      console.log('shuju ',this.tableList[0]['col1'])
    },
    /**
     * 获取单元格高度
     * @param id
     * @returns {string}
     */
    getHeightById(id) {
      const td = document.getElementById(id);
      const computedStyle = window.getComputedStyle(td);
      const height = computedStyle.height;
      return height.split('px')[0];
    },
    /**
     * 获取单元格宽度
     * @param id
     * @returns {string}
     */
    getWidthById(id) {
      const td = document.getElementById(id);
      const computedStyle = window.getComputedStyle(td);
      const width = computedStyle.width;
      return width.split('px')[0];
    },
    /**
     * 修改单元格高度
     * @param id
     * @param height
     */
    changeHeight(id, height) {
      const td = document.getElementById(id);
      td.style.height = height;
    },
    /**
     * 修改单元格宽度
     * @param id
     * @param width
     */
    changeWidth(id, width) {
      const td = document.getElementById(id);
      td.style.width = width;
    },
    /**
     * 获取单元格边框
     * @returns {string}
     */
    getTdPadding() {
      const td = document.querySelector('td');
      return window.getComputedStyle(td).padding;
    },
    /**
     * 获取单元格边框
     * @returns {string}
     */
    getTdBorder() {
      const td = document.querySelector('td');
      return window.getComputedStyle(td).border;
    },
    /**
     * 鼠标按下单元格高度
     * @param event
     */
    onMouseDownTdHeight(event) {
      const id = event.target.id;
      // console.log('当前点击的id',id)

      this.currentClickEditDivCellId = id
      // console.log(event.target.classList.contains('tdBottomClass'))
      if (!event.target.classList.contains('tdBottomClass')) {
        return;
      }
      const tdRow = id.toString().split('_')[id.toString().split('_').length - 2];
      const tdCol = id.toString().split('_')[id.toString().split('_').length - 1];

      let mouseY = event.clientY;
      let relativeY = mouseY - document.querySelector('table').offsetTop;
      document.addEventListener('mouseup', onMouseUp);
      document.addEventListener('mousemove', onMouseMove);
      function onMouseUp(event) {
        document.removeEventListener('mousemove', onMouseMove);
        document.removeEventListener('mouseup', onMouseUp);
      }
      function onMouseMove(event) {
        mouseY = event.clientY;
        relativeY = mouseY - document.querySelector('table').offsetTop;
        let tdMinHeight = 60;
        if (relativeY > tdMinHeight) {
          let currentTd = document.getElementById(`myTd_${tdRow}_${tdCol}`);
          let offsetTop = currentTd.offsetTop - document.querySelector('table').offsetTop;
          changeHeight(`myTd_${tdRow}_${tdCol}`, relativeY - offsetTop + 'px');
        } else if (relativeY < tdMinHeight) {
          changeHeight(`myTd_${tdRow}_${tdCol}`, tdMinHeight + 'px');
        }
      }
      function changeHeight(id, height) {
        const td = document.getElementById(id);
        td.style.height = height;
      }
    },
    /**
     * 鼠标按下单元格宽度
     * @param event
     */
    onMouseDownTdWidth(event) {
      if (!event.target.classList.contains('tdRightClass')) {
        return;
      }
      const id = event.target.id;
      const tdRow = id.toString().split('_')[id.toString().split('_').length - 2];
      const tdCol = id.toString().split('_')[id.toString().split('_').length - 1];
      let mouseX = event.clientX;
      let relativeX = mouseX - document.querySelector('table').offsetLeft;
      document.addEventListener('mouseup', onMouseUp);
      document.addEventListener('mousemove', onMouseMove);
      function onMouseUp(event) {
        document.removeEventListener('mousemove', onMouseMove);
        document.removeEventListener('mouseup', onMouseUp);
      }
      function onMouseMove(event) {
        mouseX = event.clientX;
        relativeX = mouseX - document.querySelector('table').offsetLeft;
        let tdMinWidth = 150;
        if (relativeX > tdMinWidth) {
          let currentTd = document.getElementById(`myTd_${tdRow}_${tdCol}`);
          let offsetLeft = currentTd.offsetLeft - document.querySelector('table').offsetLeft;
          changeWidth(`myTd_${tdRow}_${tdCol}`, relativeX - offsetLeft + 'px');
        }
        else if (relativeX < tdMinWidth) {
          changeWidth(`myTd_${tdRow}_${tdCol}`, tdMinWidth + 'px');
        }
      }
      function changeWidth(id, width) {
        const td = document.getElementById(id);
        td.style.width = width;
      }
    },
    /**
     * 添加行
     */
    addRow() {
      const newRow = {};
      this.tableHeaders.forEach(header => {
        newRow[header] = '';
      });
      this.tableList.push(newRow);
      this.$nextTick(() => {
        this.refreshRightKeyListener()
      })
    },
    /**
     * 删除行
     */
    deleteRow() {
      this.tableList.pop();
    },
    /**
     * 添加列
     */
    addColumn() {
      const newHeader = `col${this.tableHeaders.length + 1}`;
      this.tableHeaders.push(newHeader);
      this.tableList.forEach(row => {
        row[newHeader] = '';
      });
      this.$nextTick(() => {
        this.refreshRightKeyListener()
      })
    },
    /**
     * 删除列
     */
    deleteColumn() {
      if (this.tableHeaders.length > 0) {
        const removedHeader = this.tableHeaders.pop();
        this.tableList.forEach(row => {
          delete row[removedHeader];
        });
      }
    },
    /**
     * 插入图片
     */
    addImage: function () {
      // alert('尚未完善!禁用!')
      // return;
      if (this.currentClickEditDivCellId === '') {
        return
      }
      // 向id为currentClickEditDivCellId的元素内插入图片
      // console.log(this.currentClickEditDivCellId);
      let currentCell = document.getElementById(this.currentClickEditDivCellId);
      let currentClickEditDivCellId = this.currentClickEditDivCellId
      // 生成一个file类型的输入框
      let fileInput = document.createElement('input');
      fileInput.type = 'file';
      fileInput.accept = 'image/*';
      fileInput.style.display = 'none';
      fileInput.addEventListener('change', function (event){
        const file = event.target.files[0];
        console.log(file);
        if (file) {
          const reader = new FileReader();
          reader.onload = function (e) {
            const img = document.createElement('img');
            img.src = e.target.result;
            img.alt = '插入的图片';
            img.style.maxWidth = '100px';
            img.style.maxHeight = '100px';
            const currentCell = document.getElementById(currentClickEditDivCellId);
            currentCell.appendChild(img);
          };
          reader.readAsDataURL(file);
        }
      })
      fileInput.click();
    },
    /**
     * 右键菜单的监听
     */
    startRightKeyListener() {
      const contextMenu = document.getElementById('context-menu');
      function showContextMenu(event) {
        // console.log('startRightKeyListener');
        event.preventDefault(); // 关闭原浏览器的右键菜单
        const x = event.clientX;
        const y = event.clientY;
        contextMenu.style.top = y + 'px';
        contextMenu.style.left = x + 'px';
        contextMenu.classList.remove('hidden');
      }
      function hideContextMenu() {
        contextMenu.classList.add('hidden');
      }
      // 右键点击事件   给所有表格都加上右键点击事件
      document.querySelectorAll('td').forEach(td => {
        td.addEventListener('contextmenu', showContextMenu);
      });
      document.addEventListener('click', function (event) {
        if (event.target!== contextMenu &&!contextMenu.contains(event.target)) {
          hideContextMenu();
        }
      });
      document.addEventListener('keydown', function (event) {
        if (event.key === 'Escape') {
          hideContextMenu();
        }
      });
    },
    /**
     * 刷新右键的监听
     * */
    refreshRightKeyListener(){
      const contextMenu = document.getElementById('context-menu');
      function showContextMenu(event) {
        // console.log('startRightKeyListener');
        event.preventDefault(); // 关闭原浏览器的右键菜单
        const x = event.clientX;
        const y = event.clientY;
        contextMenu.style.top = y + 'px';
        contextMenu.style.left = x + 'px';
        contextMenu.classList.remove('hidden');
      }
      function hideContextMenu() {
        contextMenu.classList.add('hidden');
      }
      // 右键点击事件   给所有表格都加上右键点击事件
      document.querySelectorAll('td').forEach(td => {
        td.addEventListener('contextmenu', showContextMenu);
      });
    },
    /**
     * 关闭右键菜单的监听
     */
    closeRightKeyListener(){
      const contextMenu = document.getElementById('context-menu');
      function showContextMenu(event) {
        event.preventDefault();
        const x = event.clientX;
        const y = event.clientY;
        contextMenu.style.top = y + 'px';
        contextMenu.style.left = x + 'px';
        contextMenu.classList.remove('hidden');
      }
      function hideContextMenu() {
        contextMenu.classList.add('hidden');
      }
      document.querySelectorAll('td').forEach(td => {
        td.removeEventListener('contextmenu', showContextMenu);
      });
      // document.getElementById('keys_0_0').removeEventListener('contextmenu', showContextMenu);
      document.removeEventListener('click', function (event) {
        if (event.target!== contextMenu &&!contextMenu.contains(event.target)) {
          hideContextMenu();
        }
      });
      document.removeEventListener('keydown', function (event) {
        if (event.key === 'Escape') {
          hideContextMenu();
        }
      });
   }
  },
  /**
   * 挂载完成后
   */
  mounted() {
    // 获取table
    const table = document.querySelector('table');
    table.addEventListener('mousedown', this.onMouseDownTdHeight);
    table.addEventListener('mousedown', this.onMouseDownTdWidth);
    this.startRightKeyListener()
  },
  /**
   * 销毁前
   */
  beforeDestroy() {
    /**
     * 移除事件监听
     */
    document.removeEventListener('mousedown', this.onMouseDownTdHeight);
    document.removeEventListener('mousedown', this.onMouseDownTdWidth);
    this.closeRightKeyListener()
  },
};
</script>

<style scoped>
table {
  border-collapse: collapse;
}
th,
td {
  border: 1px solid black;
  padding: 0;
}

.tdBottomClass {
  position: relative;
  padding: 0;
}
.tdBottomClass::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 2px;
  /*background-color: rgb(218, 71, 71);*/
  cursor: s-resize; /* 南北方向的调整 */
  z-index: 10;
}
.tdRightClass {
  /*position: relative;*/
  padding: 0;
  position: absolute;
  top: 0;
  right: 0;
  width: 2px;
  height: 100%;
  /*background-color: rgb(218, 71, 71);*/
  cursor: w-resize; /* 东西方向的调整 */
  z-index: 10;
}

td {
  width: 150px;
  height: 60px;
}
.editDiv {
  text-align: left;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  resize: none;
  overflow: hidden;
  border: 0;
  margin: 0;
  padding: 2px;
  word-wrap: break-word;
  word-break: break-all;
}
.editDiv:focus {
  text-align: left;
  outline: 1px solid #369a1d;
  background-color: rgba(66, 185, 131, 0.3);
  height: 100%;
  z-index: 99;
  padding: 2px;
  word-wrap: break-word;
  word-break: break-all;
}

#context-menu {
  position: absolute;
  background-color: #f9f9f9;
  border: 1px solid #ccc;
  box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.3);
  padding: 5px;
  z-index: 1000;
}

#context-menu ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
}

#context-menu li {
  padding: 5px;
}

#context-menu li:hover {
  background-color: #e9e9e9;
}

.hidden {
  display: none;
}
</style>